package commons.utils.primitive_geom;

import commons.errors.ErrorsHandler;

// Utilisé pour optimiser certains traitements
// Les bounds sont calculée à la construction du segment, mais sont
//   à mettre à jour manuellement a chaque mouvement des extrémités !!
public class Segment_bound extends Segment_d {
	
	
	public double xMin, xMax, yMin, yMax;

	public Segment_bound() {
		super();
		updateBound();
	}

	public Segment_bound(Segment_d seg) {
		super(seg);
		updateBound();
	}

	public Segment_bound(Point_d pt1, Point_d pt2) {
		super(pt1, pt2);
		updateBound();
	}

	public Segment_bound(double x1, double y1, double x2, double y2) {
		super(x1, y1, x2, y2);
		updateBound();
	}
	
	public boolean boundingBoxIntersect(Segment_bound seg2) {
		if (ErrorsHandler.assertsEnabled) {
			this.assertCheckBound();
			seg2.assertCheckBound();
		}
		if (this.xMax<seg2.xMin || this.xMin>seg2.xMax || this.yMax<seg2.yMin || this.yMin>seg2.yMax)
			return false;
		else
			return true;
	}
	
	public boolean boundingBoxIntersect(double seg2_xMin, double seg2_xMax, double seg2_yMin, double seg2_yMax) {
		if (ErrorsHandler.assertsEnabled) {
			this.assertCheckBound();
		}
		if (this.xMax<seg2_xMin || this.xMin>seg2_xMax || this.yMax<seg2_yMin || this.yMin>seg2_yMax)
			return false;
		else
			return true;
	}
	
	public boolean boundingBoxIntersect(Point_d pt1, Point_d pt2) {
		if (ErrorsHandler.assertsEnabled) {
			this.assertCheckBound();
		}
		
		double seg2_xMin, seg2_xMax, seg2_yMin, seg2_yMax;
		if (pt1.x < pt2.x) {
			seg2_xMin = pt1.x;
			seg2_xMax = pt2.x;
		} else {
			seg2_xMin = pt2.x;
			seg2_xMax = pt1.x;
		}
		if (pt1.y < pt2.y) {
			seg2_yMin = pt1.y;
			seg2_yMax = pt2.y;
		} else {
			seg2_yMin = pt2.y;
			seg2_yMax = pt1.y;
		}
		
		if (this.xMax<seg2_xMin || this.xMin>seg2_xMax || this.yMax<seg2_yMin || this.yMin>seg2_yMax)
			return false;
		else
			return true;
	}
	
	final public void updateBound() {
		if (this.pt1.x <= this.pt2.x) {
			xMin = this.pt1.x;
			xMax = this.pt2.x;
		} else {
			xMin = this.pt2.x;
			xMax = this.pt1.x;
		}
		if (this.pt1.y <= this.pt2.y) {
			yMin = this.pt1.y;
			yMax = this.pt2.y;
		} else {
			yMin = this.pt2.y;
			yMax = this.pt1.y;
		}
	}
	
	public void assertCheckBound() {
		if (ErrorsHandler.assertsEnabled) {
			assert(xMin == Math.min(pt1.x, pt2.x));
			assert(xMax == Math.max(pt1.x, pt2.x));
			assert(yMin == Math.min(pt1.y, pt2.y));
			assert(yMax == Math.max(pt1.y, pt2.y));
		}
	}
}
